﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using System.Drawing;

namespace AirHockey
{
    public class Model:IDrawableComponent
    {
        #region Members
        private bool initialized;
        private char[] splitChars = { ' ' };
        private char[] deleteChars = { '\t', '\r', '\n', ' ' };
        private List<Material> materials;
        private Mesh mesh;
        private Matrix4 modelView;
        private Texture texture;//if null, determine which shader program to use
        #endregion

        #region Properties
        public bool Initialized
        {
            get { return initialized; }
        }

        public bool Visible
        {
            get;
            set;
        }

        public int DrawOrder
        {
            get;
            set;
        }

        public List<Material> Materials
        {
            get { return materials; }
        }

        public Mesh Mesh
        {
            get { return mesh; }
            set { mesh = value; }
        }

        public Matrix4 ModelView
        {
            get { return modelView; }
        }

        public Material Material
        {
            get { return materials[0]; }
        }

        public Texture Texture
        {
            get { return texture; }
            set { texture = value; }
        }
        #endregion

        #region Constructor
        public Model()
        {
            materials = new List<Material>();
            mesh = null;
            modelView = Matrix4.Scale(20f,20f,20f);
            //modelView = Matrix4.CreateTranslation(new Vector3(-1f,0f, 1f));
            
        }
        #endregion

        #region Public Methods
        public void AddMaterial(Material material)
        {
            materials.Add(material);
        }

        public Material GetMaterial(string name)
        {
            foreach (Material mat in materials)
            {
                if (mat.MaterialName == name)
                {
                    return mat;
                }
            }

            return null;
        }

        public void Draw()
        {
            GL.Enable(EnableCap.Texture2D);

            GL.EnableVertexAttribArray(0);
            GL.EnableVertexAttribArray(1);
            GL.EnableVertexAttribArray(2);
            
            GL.BindTexture(TextureTarget.Texture2D,texture.Id);
            GL.BindBuffer(BufferTarget.ArrayBuffer, mesh.vbo);

            GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (float)TextureEnvMode.Modulate);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMinFilter.Linear);

            GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest);

            GL.VertexAttribPointer(0, 4, VertexAttribPointerType.Float, false, VertexInterleaved.VertexStride(), 0);
            GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, VertexInterleaved.VertexStride(), 0);
            GL.VertexAttribPointer(2, 2, VertexAttribPointerType.Float, false, VertexInterleaved.VertexStride(), 0);
            
            GL.DrawArrays(BeginMode.Triangles, 0, mesh.vertices.Length);

            GL.DisableVertexAttribArray(0);
            GL.DisableVertexAttribArray(1);
            GL.DisableVertexAttribArray(2);

            GL.Disable(EnableCap.Texture2D);
        }

        public void Initialize()
        {
            GL.GenBuffers(1, out mesh.vbo);
            GL.BindBuffer(BufferTarget.ArrayBuffer, mesh.vbo);
            GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(mesh.vertices.Length * VertexInterleaved.VertexStride()), mesh.vertices, BufferUsageHint.StaticDraw);
            initialized = true;
            Visible = true;
        }
        #endregion
    }
}
